package com.cy.store.service.impl;

import cn.hutool.core.util.IdUtil;
import com.cy.store.mapper.UserMapper;
import com.cy.store.pojo.User;
import com.cy.store.service.IMailService;
import com.cy.store.service.IUserService;
import com.cy.store.service.ex.*;
import com.sun.org.apache.bcel.internal.generic.IFEQ;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import javax.servlet.http.HttpSession;
import java.time.LocalDateTime;
import java.util.*;

/**
 * @PROJECT_NAME: store
 * @DESCRIPTION:
 * @USER: 28416
 * @DATE: 2022/11/2 17:56
 */
@Service  //交给springboot来进行管理
public class UserServiceImpl implements IUserService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private IMailService mailService;
    @Override
    public void reg(User user) {
        //调用findByUsernam 方法  判断用户名是否被注册过
        String username = user.getUsername();

        User byUsername = userMapper.findByUsername(username);
        if (byUsername != null){
            throw new UsernameDuplicatedException("用户名被占用");
        }
        //设置email


        //密码加密处理的实现：md5算法
        //串+ paaword +串   ---整体尽心md5算法加密  -- 连续加密三次
        // 串被称为盐值    盐值 + password + 盐值 --随机的字符串而已
        String oldPassword = user.getPassword();
        //获取字符串（盐值） ----随机生成
        String salt = UUID.randomUUID().toString().toUpperCase();
        //将密码和盐值作为整体进行加密处理
        String md5Password = getMd5Password(oldPassword, salt);
        user.setSalt(salt); //设置salt  以后在登录时候进行比较

        //将加密之后的密码重新补全设置到user对象中
        user.setPassword(md5Password);

        //补全第一次注册时用户的数据
        user.setIsDelete(0);
        user.setCreatedUser(user.getUsername());
        user.setModifiedUser(user.getUsername());
        //设置两个时间
        Date date = new Date();
        user.setCreatedTime(date);
        user.setModifiedTime(date);

        //邮箱注册功能补全
        String confirmCode = IdUtil.createSnowflake(1, 1).nextIdStr();
        LocalDateTime ldt = LocalDateTime.now().plusDays(1);
        user.setConfirmCode(confirmCode);
        user.setActivationTime(ldt);
        user.setIsValid((byte) 0);
        //执行注册业务功能实现
        Integer insert = userMapper.insert(user);
        if (insert != 1){
            throw  new InsertException("在用户注册中产生了位置的异常");
        }else{
            //TODO 发送邮箱
            String activationUrl = "http://localhost:8080/users/activation?confirmCode=" + confirmCode;
            mailService.sendMailForActivationAccount(activationUrl, user.getEmail());
        }

    }

    /**
     * 登录方法
     * @param username
     * @param password
     * @return
     */
    @Override
    public User login(String username, String password) {
        Map<String, Object> resultMap = new HashMap<>();
        User byUsername = userMapper.findByUsername(username);
        if (byUsername == null) {
            throw new UsernameNotFoundException("用户数据不存在");
        }

        Integer isDelete = byUsername.getIsDelete();
        if (isDelete == 1) {
            throw new UsernameNotFoundException("用户被删除");
        }
        //邮箱验证

        // 查询不到结果，返回：该账户不存在或未激活
        if (byUsername.getIsValid() != 1){
            throw new UserNotInitException("用户未激活");
        }
        //检测用户的密码是否匹配
        String salt = byUsername.getSalt();
        String password1 = byUsername.getPassword();
        String md5Password = getMd5Password(password, salt);
        if (!password1.equals(md5Password)){
            throw new PasswordNotMatchException("用户密码错误");
        }
        //判断用户是否被注销


        //user对象是为了辅助其他页面做数据展示作用的，只涉及到username  uid 以及头像
        //数据量体量小  传输效率更快  提升了系统的性能
        User user = new User();
        user.setUsername(byUsername.getUsername());
        user.setUid(byUsername.getUid());
        user.setAvatar(byUsername.getAvatar());
        return user;
    }

    @Override
    public void changePassword(Integer uid, String username, String oldPassword, String newPassword) {
        //
        User byUid = userMapper.findByUid(uid);
        if (byUid == null || byUid.getIsDelete() == 1){
            throw new UsernameNotFoundException("用户数据不存在");
        }
        //原始密码和数据库中的数据进行比较
        String oldMd5Password = getMd5Password(oldPassword, byUid.getSalt());
        if ( !byUid.getPassword().equals(oldMd5Password)){
            throw new PasswordNotMatchException("账号密码不匹配");
        }
        //存入新的密码
        String newMd5Password = getMd5Password(newPassword, byUid.getSalt());
        Integer integer = userMapper.updatepasswrodByUid(uid, newMd5Password, username, new Date());
        if (integer != 1) {
            throw  new UpdateException("更新数据时产生未知的异常");
        }


    }

    /**
     * 在个人资料修改的过程中使用此方法先判断用户是否存在
     * @param uid
     * @return
     */
    @Override
    public User getByUid(Integer uid) {
        User result= userMapper.findByUid(uid);
        if (result == null || result.getIsDelete() == 1) {
            throw new UsernameNotFoundException("用户没有被找到");
        }
        //中间类 减少数据传输之间的
        User user = new User();
        user.setGender(result.getGender());
        user.setUsername(result.getUsername());
        user.setPhone(result.getPhone());
        user.setEmail(result.getEmail());
        return  user;
    }

    /**
     * 修改个人信息的方法  调用usermapper 的 updateInfoByuid方法
     * @param uid
     * @param username
     * @param user
     */
    @Override
    public void changeInfo(Integer uid, String username, User user) {
        User result = userMapper.findByUid(uid);
        if (result == null || result.getIsDelete() == 1) {
            throw new UsernameNotFoundException("用户没有被找到");
        }
        user.setUid(uid);
        //user.setUsername(username);
        user.setModifiedTime(new Date());
        user.setModifiedUser(username);


        Integer integer = userMapper.updateInfoByUid(user);
        if (integer != 1) {
            throw new UpdateException("更新数据时产生未知的异常");
        }

    }

    /**
     * 更新用户的头像
     * @param uid
     * @param avatar
     * @param username
     */
    @Override
    public void changeAvatar(Integer uid, String avatar, String username) {
        // 建议查询当前的用户是否存在
        User result = userMapper.findByUid(uid);
        if (result == null || result.getIsDelete().equals(1)) {
            throw  new UsernameNotFoundException("用户数据不存在");
        }
        //上传头像
        Integer integer = userMapper.updateAvatarByUid(uid, avatar, username, new Date());
        if (integer != 1) {
            throw  new UpdateException("更新时产生了未知的错误");
        }

    }
    @Override
    public void activationAccont(String confirmCode) {
        // 根据确认码查询用户
        User user = userMapper.selectUserByConfirmCode(confirmCode);
//        // 判断激活时间是否超时
//        boolean after = LocalDateTime.now().isAfter(user.getActivationTime());
//        if (after) {
//           throw new RuntimeException("超时");
//        }
        // 根据确认码查询用户并修改状态值为 1（可用）
        int result = userMapper.updateUserByConfirmCode(confirmCode);
//        if (result != 1) {
//            throw new RuntimeException("更新失败");
//        }
    }
    private String getMd5Password(String password,String salt){
        //md5加密算法
        for (int i = 0; i < 3; i++) {
            password = DigestUtils.md5DigestAsHex((salt+password+salt).getBytes()).toUpperCase();
        }
        //返回加密之后的密码
        return  password;
    }

}
